#include <osa.h>
#include <avr/io.h>
#include <stdio.h> 
#include <string.h> 
#include <avr/eeprom.h>

#include "main.h"
#include "manage.h"
#include "rtc.h"
#include "disp.h"
#include "keyin.h"
#include "BuffFifo.h"

const char cVersion[] = "\r\nLampControl 0.1\r\n";

enum
{
	EDIT_TIME_MODE_NONE=0,
	EDIT_TIME_MODE_CURR_DISP,
	EDIT_TIME_MODE_ON_DISP,
	EDIT_TIME_MODE_OFF_DISP
};

enum
{
	EDIT_TIME_FLAG_NONE=0,
	EDIT_TIME_FLAG_HOUR,
	EDIT_TIME_FLAG_MINUTE,
	EDIT_TIME_FLAG_DISABLE
};

enum
{
	MANAGE_TIME_NULL_DISP_CMD=0,
	MANAGE_TIME_MENU_DISP_CMD,
	MANAGE_TIME_DISP_CMD,
	MANAGE_TOGGLE_DISP_CMD,
	MANAGE_TOGGLE_TIME_DISP_CMD,
	MANAGE_TIME_ENABLE_CMD,
	MANAGE_TIME_DISABLE_CMD,
	MANAGE_TIME_UP_DISP_CMD,
	MANAGE_TIME_UP_CONT_DISP_CMD,
	MANAGE_TIME_DOWN_DISP_CMD,
	MANAGE_TIME_DOWN_CONT_DISP_CMD,
	MANAGE_TIME_CURR_SETUP_CMD,
	MANAGE_WRITE_EPPROM_TIME_ON_CMD,
	MANAGE_READ_EPPROM_TIME_ON_CMD,
	MANAGE_WRITE_EPPROM_TIME_OFF_CMD,
	MANAGE_READ_EPPROM_TIME_OFF_CMD,	
	MANAGE_SET_LAMP_ON_CMD,
	MANAGE_SET_LAMP_OFF_CMD,
	MANAGE_SET_LAMP_ON_DISP_CMD,
	MANAGE_SET_LAMP_OFF_DISP_CMD,
	MANAGE_SET_BLACK_OUT_CMD,
	MANAGE_TIME_CURR_DISP_CMD,

};


#define TIME_BLKSIZE 3
struct{
	char curr     [TIME_BLKSIZE];
	char time_on  [TIME_BLKSIZE];
	char time_off [TIME_BLKSIZE];
}
manage_time;

struct{
	char edit_flag;	
	char edit_mode;
	char prv_key;
	signed int cmd_time_out;
	signed int cmd_black_out;
}
manage_flg;

#define MANAGE_TIME_INTERVAL 100 ms

#define LAMP_CTR_PORT 	PORTD
#define LAMP_CTR_PIN  	PIND
#define LAMP_CTR_DIR  	DDRD
#define LAMP_CTR  		PD6

// unsigned char EEMEM EppromTimeOn[TIME_BLKSIZE] = {0,0,0};
// unsigned char EEMEM EppromTimeOff[TIME_BLKSIZE] = {0,0,0};
unsigned char EEMEM EppromTimeOnOff[6];

#define EEADDR_TIME_ON  0x00
#define EEADDR_TIME_OFF (EEADDR_TIME_ON + TIME_BLKSIZE)

#define MANAGE_COMMAND_BUFF 50
BUFF_DECL_FIFO(Manage_Command_Buff,MANAGE_COMMAND_BUFF); 

#define MANAGE_CMD_TIMEOUT 2500 ms
#define MANAGE_CMD_BLACK_OUT 10000 ms

/********************************************************************************
 *                                                                              *
 *  TASK:           InitManage                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void InitManage( void )
{
	//initiai time 
	memset((void *)((char *)&manage_time),0,sizeof(manage_time));
	
	// manage_time.time_on[0] = TRUE;
	// manage_time.time_on[1] = 12;
	// manage_time.time_on[2] = 34;
	
	manage_flg.edit_flag = EDIT_TIME_FLAG_NONE;
	manage_flg.edit_mode = EDIT_TIME_MODE_NONE;
	manage_flg.prv_key = KEY_NULL_CODE;
	manage_flg.cmd_time_out = 0;
	manage_flg.cmd_black_out = MANAGE_CMD_BLACK_OUT;

	BUFF_INIT_FIFO(Manage_Command_Buff);
	
	LAMP_CTR_PORT &= ~_BV(LAMP_CTR); //set pin to low
	LAMP_CTR_DIR  |= _BV(LAMP_CTR);  //Output mode
}


/********************************************************************************
 *                                                                              *
 *  TASK:           RTCMailManage                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void RTC_Mail_Manage (void)
{
	OST_MSG rtc_msg;
	
	if (OS_Msg_Check (os_msg_rtc_update_cb)) {     // If message exists
		OS_Msg_Accept(os_msg_rtc_update_cb, rtc_msg);  // then accept it.
		
		if(manage_flg.edit_flag == EDIT_TIME_FLAG_NONE){
			manage_time.curr[0] = TRUE;
			manage_time.curr[1] = ((char *)rtc_msg)[0];
			manage_time.curr[2] = ((char *)rtc_msg)[1];
		}
		
		//@TH printf("Time %02d:%02d\r\n",(int)((char *)rtc_msg)[0],(int)((char *)rtc_msg)[1]);
	};
	
}



/********************************************************************************
 *                                                                              *
 *  TASK:           Keyin_Mail_Manage                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Keyin_Mail_Manage (void)
{
// static unsigned char rtc_time[2];
   OST_SMSG smsg_keyin;
   //static ST_DISP_MSG manege_disp_msg;
      
	if (OS_Smsg_Check (os_smsg_keyin)) {     // If smsg present
		OS_Smsg_Accept(os_smsg_keyin, smsg_keyin);
		
		if(manage_flg.cmd_black_out == 0)
		{
			manage_flg.cmd_black_out = MANAGE_CMD_BLACK_OUT;
			BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_CURR_DISP_CMD);
		}
		else
		{
			if(smsg_keyin==(KEY_MODE_ID | KEY_DOWN_CODE) && manage_flg.prv_key == (KEY_MODE_ID | KEY_UP_CODE))		
			{			
				if( manage_flg.edit_flag == EDIT_TIME_FLAG_NONE )
				{		
					if(manage_flg.edit_mode == EDIT_TIME_MODE_NONE || manage_flg.edit_mode == EDIT_TIME_MODE_CURR_DISP)
					{
						manage_flg.edit_mode = EDIT_TIME_MODE_ON_DISP;
					}
					else if(manage_flg.edit_mode == EDIT_TIME_MODE_ON_DISP)
					{
						manage_flg.edit_mode = EDIT_TIME_MODE_OFF_DISP;
					}
					else if(manage_flg.edit_mode == EDIT_TIME_MODE_OFF_DISP)
					{
						manage_flg.edit_mode = EDIT_TIME_MODE_CURR_DISP;
					}
					BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_MENU_DISP_CMD);
					BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_DISP_CMD);
					
				}
				else 
				{
					if(manage_flg.edit_flag == EDIT_TIME_FLAG_NONE ||  manage_flg.edit_flag == EDIT_TIME_FLAG_DISABLE)
					{
						BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_ENABLE_CMD);
						manage_flg.edit_flag = EDIT_TIME_FLAG_HOUR;
					}
					else if(manage_flg.edit_flag == EDIT_TIME_FLAG_HOUR)
					{
						manage_flg.edit_flag = EDIT_TIME_FLAG_MINUTE;				
					}
					else if(manage_flg.edit_flag == EDIT_TIME_FLAG_MINUTE)
					{
						BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_DISABLE_CMD);
						manage_flg.edit_flag = EDIT_TIME_FLAG_DISABLE;				
					}				
					BuffPutFifo(Manage_Command_Buff,MANAGE_TOGGLE_DISP_CMD);				
				}
				manage_flg.cmd_time_out = MANAGE_CMD_TIMEOUT;			
			}
			else if(smsg_keyin==(KEY_MODE_ID | KEY_HOLD_CODE) && manage_flg.prv_key == (KEY_MODE_ID | KEY_UP_CODE))			
			{
				if(manage_flg.edit_mode != EDIT_TIME_MODE_NONE)
				{
					if( manage_flg.edit_flag == EDIT_TIME_FLAG_NONE )
					{
						manage_flg.edit_flag = EDIT_TIME_FLAG_HOUR;
						BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_ENABLE_CMD);
						BuffPutFifo(Manage_Command_Buff,MANAGE_TOGGLE_DISP_CMD);
					}
					else
					{
						manage_flg.edit_flag = EDIT_TIME_FLAG_NONE;
						BuffPutFifo(Manage_Command_Buff,MANAGE_TOGGLE_TIME_DISP_CMD);
						BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_DISP_CMD);
						if(manage_flg.edit_mode == EDIT_TIME_MODE_CURR_DISP)
						{
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_CURR_SETUP_CMD);				
						}				
						else if(manage_flg.edit_mode == EDIT_TIME_MODE_ON_DISP)
						{
							BuffPutFifo(Manage_Command_Buff,MANAGE_WRITE_EPPROM_TIME_ON_CMD);				
						}
						else if(manage_flg.edit_mode == EDIT_TIME_MODE_OFF_DISP)
						{
							BuffPutFifo(Manage_Command_Buff,MANAGE_WRITE_EPPROM_TIME_OFF_CMD);				
						}
					}
					manage_flg.cmd_time_out = MANAGE_CMD_TIMEOUT;
				}
			}
			else if(smsg_keyin==(KEY_UP_ID | KEY_DOWN_CODE) && manage_flg.prv_key == (KEY_UP_ID | KEY_UP_CODE))			
			{
				if(manage_flg.edit_mode != EDIT_TIME_MODE_NONE)
				{
					if( manage_flg.edit_flag != EDIT_TIME_FLAG_NONE )
					{
						if(manage_flg.edit_flag == EDIT_TIME_FLAG_DISABLE)
						{
							manage_flg.edit_flag = EDIT_TIME_FLAG_HOUR;
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_ENABLE_CMD);
							BuffPutFifo(Manage_Command_Buff,MANAGE_TOGGLE_DISP_CMD);
						}
						else
						{
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_UP_DISP_CMD);
						}
					}
					manage_flg.cmd_time_out = MANAGE_CMD_TIMEOUT;
				}
			}
			else if(smsg_keyin==(KEY_UP_ID | KEY_HOLD_CODE) && manage_flg.prv_key == (KEY_UP_ID | KEY_UP_CODE))			
			{
				if(manage_flg.edit_mode != EDIT_TIME_MODE_NONE)
				{
					if( manage_flg.edit_flag != EDIT_TIME_FLAG_NONE )
					{
						if(manage_flg.edit_flag == EDIT_TIME_FLAG_DISABLE)
						{
							manage_flg.edit_flag = EDIT_TIME_FLAG_HOUR;
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_ENABLE_CMD);
							BuffPutFifo(Manage_Command_Buff,MANAGE_TOGGLE_DISP_CMD);
						}
						else
						{
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_UP_CONT_DISP_CMD);
						}
					}
					manage_flg.cmd_time_out = MANAGE_CMD_TIMEOUT;			
				}
			}		
			else if(smsg_keyin==(KEY_UP_ID | KEY_DOWN_CODE) && manage_flg.prv_key == (KEY_UP_ID | KEY_HOLD_CODE))			
			{
				if(manage_flg.edit_mode != EDIT_TIME_MODE_NONE)
				{			
					if( manage_flg.edit_flag != EDIT_TIME_FLAG_NONE )
					{
						if(manage_flg.edit_flag == EDIT_TIME_FLAG_DISABLE)
						{
							manage_flg.edit_flag = EDIT_TIME_FLAG_HOUR;
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_ENABLE_CMD);
						}
						else
						{
							BuffFlushFifo(Manage_Command_Buff);
						}
						BuffPutFifo(Manage_Command_Buff,MANAGE_TOGGLE_DISP_CMD);
					}
					manage_flg.cmd_time_out = MANAGE_CMD_TIMEOUT;			
				}
			}				
			else if(smsg_keyin==(KEY_DOWN_ID | KEY_DOWN_CODE) && manage_flg.prv_key == (KEY_DOWN_ID | KEY_UP_CODE))			
			{
				if(manage_flg.edit_mode != EDIT_TIME_MODE_NONE)
				{
					if( manage_flg.edit_flag != EDIT_TIME_FLAG_NONE )
					{
						if(manage_flg.edit_flag == EDIT_TIME_FLAG_DISABLE)
						{
							manage_flg.edit_flag = EDIT_TIME_FLAG_HOUR;
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_ENABLE_CMD);
							BuffPutFifo(Manage_Command_Buff,MANAGE_TOGGLE_DISP_CMD);
						}
						else
						{
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_DOWN_DISP_CMD);
						}
					}
					manage_flg.cmd_time_out = MANAGE_CMD_TIMEOUT;			
				}
			}
			else if(smsg_keyin==(KEY_DOWN_ID | KEY_HOLD_CODE) && manage_flg.prv_key == (KEY_DOWN_ID | KEY_UP_CODE))			
			{
				if(manage_flg.edit_mode != EDIT_TIME_MODE_NONE)
				{				
					if( manage_flg.edit_flag != EDIT_TIME_FLAG_NONE )
					{
						if(manage_flg.edit_flag == EDIT_TIME_FLAG_DISABLE)
						{
							manage_flg.edit_flag = EDIT_TIME_FLAG_HOUR;
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_ENABLE_CMD);
							BuffPutFifo(Manage_Command_Buff,MANAGE_TOGGLE_DISP_CMD);
						}
						else
						{
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_DOWN_CONT_DISP_CMD);
						}
					}
					manage_flg.cmd_time_out = MANAGE_CMD_TIMEOUT;			
				}
			}
			else if(smsg_keyin==(KEY_DOWN_ID | KEY_DOWN_CODE) && manage_flg.prv_key == (KEY_DOWN_ID | KEY_HOLD_CODE))			
			{
				if(manage_flg.edit_mode != EDIT_TIME_MODE_NONE)
				{
					if( manage_flg.edit_flag != EDIT_TIME_FLAG_NONE )
					{
						if(manage_flg.edit_flag == EDIT_TIME_FLAG_DISABLE)
						{
							manage_flg.edit_flag = EDIT_TIME_FLAG_HOUR;
							BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_ENABLE_CMD);
						}
						else
						{
							BuffFlushFifo(Manage_Command_Buff);
						}
						BuffPutFifo(Manage_Command_Buff,MANAGE_TOGGLE_DISP_CMD);
					}
					manage_flg.cmd_time_out = MANAGE_CMD_TIMEOUT;			
				}
			}

			//@TH printf("Cmd 0x%X %d\r\n",smsg_keyin,manage_flg.edit_mode);		
			manage_flg.prv_key = smsg_keyin;
		}

	}
}


/********************************************************************************
 *                                                                              *
 *  TASK:           ManageEppromTimeOff                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void ManageEppromTimeOff(char read_write)
{
	char value;
	if( read_write == 1)
	{
		eeprom_write_byte ((uint8_t *)EPPROM_TIME_OFF_0_ADDR,manage_time.time_off[0]);
		eeprom_write_byte ((uint8_t *)EPPROM_TIME_OFF_1_ADDR,manage_time.time_off[1]);
		eeprom_write_byte ((uint8_t *)EPPROM_TIME_OFF_2_ADDR,manage_time.time_off[2]);
	}
	else
	{
		value = eeprom_read_byte((uint8_t*)EPPROM_TIME_OFF_0_ADDR); 
		if(value == 0 || value == 1)
		{
			manage_time.time_off[0] = value;
			value = eeprom_read_byte((uint8_t*)EPPROM_TIME_OFF_1_ADDR);
			if(value > 23)
			{
				manage_time.time_off[0] = FALSE;
				manage_time.time_off[1] = 0;
				manage_time.time_off[2] = 0;
			}			
			else
			{
				manage_time.time_off[1] = value;
				value = eeprom_read_byte((uint8_t*)EPPROM_TIME_OFF_2_ADDR);
				if(value > 59)
				{
					manage_time.time_off[0] = FALSE;
					manage_time.time_off[1] = 0;
					manage_time.time_off[2] = 0;
				}
				else
				{
					manage_time.time_off[2] = value; 
				}
			}
			
		}
	}
}

// /********************************************************************************
 // *                                                                              *
 // *  TASK:           ManageEppromTimeOff                                           * 
 // *                                                                              *
 // *------------------------------------------------------------------------------*
 // *
 // *  description:    
 // *
 // ********************************************************************************/
// void ManageEppromTimeOnOff(char read_write)
// {
	// //char epprom[6];
	
	// if( read_write == 1)
	// {
		// // memcpy(&epprom[0],&manage_time.time_on[0],3);
		// // memcpy(&epprom[3],&manage_time.time_off[0],3);
		// // eeprom_write_block ((const void *)&epprom[0] ,( const void *)EppromTimeOnOff, 6);
		
		// eeprom_write_byte ((uint8_t *)0,manage_time.time_on[0]);
		// eeprom_write_byte ((uint8_t *)1,manage_time.time_on[1]);
		// eeprom_write_byte ((uint8_t *)2,manage_time.time_on[2]);
		
		// eeprom_write_byte ((uint8_t *)3,manage_time.time_off[0]);
		// eeprom_write_byte ((uint8_t *)4,manage_time.time_off[1]);
		// eeprom_write_byte ((uint8_t *)5,manage_time.time_off[2]);	
	// }	
	// else
	// {
		// manage_time.time_on[0] = eeprom_read_byte((uint8_t*)0); 
		// manage_time.time_on[1] = eeprom_read_byte((uint8_t*)1); 
		// manage_time.time_on[2] = eeprom_read_byte((uint8_t*)2); 
		
		// manage_time.time_off[0] = eeprom_read_byte((uint8_t*)3); 
		// manage_time.time_off[1] = eeprom_read_byte((uint8_t*)4); 
		// manage_time.time_off[2] = eeprom_read_byte((uint8_t*)5); 
		// // eeprom_read_block(( void *)&epprom[0] , (const void *)EppromTimeOnOff , 6) ;	
		// // memcpy(&manage_time.time_on[0],&epprom[0],3);
		// // memcpy(&manage_time.time_off[0],&epprom[3],3);
	// }
// }

/********************************************************************************
 *                                                                              *
 *  TASK:           ManageEppromTimeOn                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void ManageEppromTimeOn(char read_write)
{
	char value;
	
	if( read_write == 1)
	{
		eeprom_write_byte ((uint8_t *)EPPROM_TIME_ON_0_ADDR,manage_time.time_on[0]);
		eeprom_write_byte ((uint8_t *)EPPROM_TIME_ON_1_ADDR,manage_time.time_on[1]);
		eeprom_write_byte ((uint8_t *)EPPROM_TIME_ON_2_ADDR,manage_time.time_on[2]);
	}
	else
	{
		value = eeprom_read_byte((uint8_t*)EPPROM_TIME_ON_0_ADDR); 
		if(value == 0 || value == 1)
		{
			manage_time.time_on[0] = value;
			value = eeprom_read_byte((uint8_t*)EPPROM_TIME_ON_1_ADDR);
			if(value > 23)
			{
				manage_time.time_on[0] = FALSE;
				manage_time.time_on[1] = 0;
				manage_time.time_on[2] = 0;
			}			
			else
			{
				manage_time.time_on[1] = value;
				value = eeprom_read_byte((uint8_t*)EPPROM_TIME_ON_2_ADDR);
				if(value > 59)
				{
					manage_time.time_on[0] = FALSE;
					manage_time.time_on[1] = 0;
					manage_time.time_on[2] = 0;
				}
				else
				{
					manage_time.time_on[2] = value; 
				}
			}
			
		}
	}
}

/********************************************************************************
 *                                                                              *
 *  TASK:           DisplayTimeUpdate                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Disp_Msg_Send(char act, char option, char time, char * p_value)
{
	static ST_DISP_MSG manege_disp_msg;

	manege_disp_msg.act 		= act;
	manege_disp_msg.opt_flg 	= option;
	manege_disp_msg.time_update = time;
	
	if(p_value != NULL)
	{	
		memcpy((void *)&manege_disp_msg.post[0],p_value,SEGMENT_DIGIT_MAX);
	}
	//OS_Queue_Send_Now(queue_display, (char *) &manege_disp_msg);		
	OS_Queue_Send(queue_display, (char *) &manege_disp_msg);			
}


/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Disp_Time_Update                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Disp_Time(void)
{
	char disp_value[5];
	char opt;
							
	disp_value[0] = manage_time.curr[1] /10;
	disp_value[1] = manage_time.curr[1] %10;		
	disp_value[2] = manage_time.curr[2] /10;
	disp_value[3] = manage_time.curr[2] %10;
	disp_value[4] = SEGMENT_COLON;

	opt = 0b00010000 | 0b01000000;

	Manage_Disp_Msg_Send(CLEAR_DISPLAY | NORMAL_DISPLAY
							,opt
							,0
							,&disp_value[0]);	
}

/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Disp_Time_Update                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Disp_Time_Update(void)
{
			
	if( manage_time.curr[0] == TRUE && manage_flg.edit_flag == EDIT_TIME_FLAG_NONE && manage_flg.cmd_black_out > 0)
	{						
		Manage_Disp_Time();	
		manage_time.curr[0] = FALSE;		
	}
	
}

/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Disp_Time_Setup                                      * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Disp_Time_Setup(char update)
{
	static char rtc_time[3];
	
	manage_time.curr[0] = update;
	
	memcpy((void *)&rtc_time,(void *)&manage_time.curr[0],3);
	
	OS_Msg_Send(os_msg_rtc_setup_cb, (char *)rtc_time);
}

/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Time_Menu_Disp                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
const char Manage_Display_Menu_Time_ON[SEGMENT_DIGIT_MAX] = {SEGMENT_O,SEGMENT_N,SEGMENT_ALL_OFF,SEGMENT_ALL_OFF,SEGMENT_ALL_OFF};
const char Manage_Display_Menu_Time_OFF[SEGMENT_DIGIT_MAX] = {SEGMENT_O,SEGMENT_F,SEGMENT_F,SEGMENT_ALL_OFF,SEGMENT_ALL_OFF};
const char Manage_Display_Menu_Time_CURR[SEGMENT_DIGIT_MAX] = {SEGMENT_C,SEGMENT_U,SEGMENT_R,SEGMENT_R,SEGMENT_ALL_OFF}; 
void Manage_Time_Menu_Disp(void)
{
	char * p_value = NULL; 
	
	if( manage_flg.edit_mode == EDIT_TIME_MODE_CURR_DISP)
	{
		p_value = (char *)&Manage_Display_Menu_Time_CURR[0];
	}
	else if( manage_flg.edit_mode == EDIT_TIME_MODE_ON_DISP)
	{
		p_value = (char *)&Manage_Display_Menu_Time_ON[0];
	}
	else if( manage_flg.edit_mode == EDIT_TIME_MODE_OFF_DISP)
	{
		p_value = (char *)&Manage_Display_Menu_Time_OFF[0];
	}
	
	if( p_value != NULL)
	{
		Manage_Disp_Msg_Send(CLEAR_DISPLAY | MOTION_DISPLAY
								,0b00000000
								//,80 ms
								,40 ms
								,p_value);		
	}		
}


/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Time_Menu_Disp                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
const char Manage_Display_Black_Out[SEGMENT_DIGIT_MAX] = {SEGMENT_ALL_OFF,SEGMENT_ALL_OFF,SEGMENT_ALL_OFF,SEGMENT_DOT,SEGMENT_ALL_OFF}; 
void Manage_Black_Out_Disp(void)
{
	Manage_Disp_Msg_Send(CLEAR_DISPLAY | NORMAL_DISPLAY
							,0b00000000
							,0 ms
							,(char *)&Manage_Display_Black_Out);			
}


/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Time_Disp                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
const char Manage_Display_Time_Disable[SEGMENT_DIGIT_MAX] = {SEGMENT_DAT,SEGMENT_DAT,SEGMENT_DAT,SEGMENT_DAT,SEGMENT_COLON};
void Manage_Time_Disp(char toggle_mode,char time)
{
	char * p_value = NULL; 
	char disp_value[5];
	char toggle_flg;

	if(manage_flg.edit_mode == EDIT_TIME_MODE_CURR_DISP)
	{
		disp_value[0] = manage_time.curr[1] /10;
		disp_value[1] = manage_time.curr[1] %10;		
		disp_value[2] = manage_time.curr[2] /10;
		disp_value[3] = manage_time.curr[2] %10;
		disp_value[4] = SEGMENT_COLON;			
		p_value = &disp_value[0];
	}
	else if(manage_flg.edit_mode == EDIT_TIME_MODE_ON_DISP)
	{
		if(manage_time.time_on[0] == FALSE)
		{
			p_value = (char *)&Manage_Display_Time_Disable[0];
		}
		else
		{
			disp_value[0] = manage_time.time_on[1] /10;
			disp_value[1] = manage_time.time_on[1] %10;		
			disp_value[2] = manage_time.time_on[2] /10;
			disp_value[3] = manage_time.time_on[2] %10;
			disp_value[4] = SEGMENT_COLON;	
			p_value = &disp_value[0];
		}
		
	}
	else if(manage_flg.edit_mode == EDIT_TIME_MODE_OFF_DISP)
	{
		if(manage_time.time_off[0] == FALSE)
		{
			p_value = (char *)&Manage_Display_Time_Disable[0];
		}
		else
		{
			disp_value[0] = manage_time.time_off[1] /10;
			disp_value[1] = manage_time.time_off[1] %10;		
			disp_value[2] = manage_time.time_off[2] /10;
			disp_value[3] = manage_time.time_off[2] %10;
			disp_value[4] = SEGMENT_COLON;	
			p_value = &disp_value[0];
		}
	}
	
	if( p_value != NULL)
	{
		if(toggle_mode==1)
		{
			toggle_flg = 0b00000011;
		}
		else if(toggle_mode==2)
		{
			toggle_flg = 0b00001100;
		}
		else if(toggle_mode==3)
		{
			toggle_flg = 0b00001111;
		}
		else
		{
			toggle_flg = 0b00000000;
		}
		
		Manage_Disp_Msg_Send(NORMAL_DISPLAY
								,0b00000000 | toggle_flg
								,time
								,p_value);		
	}		
}


/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Display_Output_port                                  * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Display_Output_port(char port_on)
{
	Manage_Disp_Msg_Send(PORT_OUT_DISPLAY
							,port_on
							,0
							,(char *)NULL);	
}

/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Time_Disp                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Display_Toggle(char time)
{
	if(manage_flg.edit_flag==EDIT_TIME_FLAG_HOUR)
	{
		Manage_Time_Disp(1,time);
	}
	else if(manage_flg.edit_flag==EDIT_TIME_FLAG_MINUTE)
	{
		Manage_Time_Disp(2,time);
	}
	else 
	{
		Manage_Time_Disp(3,time);
	}
}

/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Time_Up_Value                                        * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Time_Up_Value(char * p_value)
{	
	if(manage_flg.edit_flag==EDIT_TIME_FLAG_HOUR)
	{
		p_value[0]++;
		if(p_value[0] > 23)
		{
			p_value[0] = 0;
		}
	}
	else if(manage_flg.edit_flag==EDIT_TIME_FLAG_MINUTE)
	{
		p_value[1]++;
		if(p_value[1] > 59)
		{
			p_value[1] = 0;
		}
	}
}

/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Time_Up_Disp                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Time_Up_Disp(void)
{
	if( manage_flg.edit_mode == EDIT_TIME_MODE_CURR_DISP)
	{
		Manage_Time_Up_Value(&manage_time.curr[1]);
	}
	else if( manage_flg.edit_mode == EDIT_TIME_MODE_ON_DISP)
	{
		if( manage_time.time_on[0] == FALSE)
		{
			manage_time.time_on[0] = TRUE;		
			Manage_Time_Up_Value(&manage_time.time_on[1]);
		}
		else
		{
			// if(manage_flg.edit_flag==EDIT_TIME_FLAG_HOUR && (manage_time.time_on[1]+1) > 23)
			// {
				// manage_time.time_on[0] = FALSE;		
			// }
			// else
			{
				Manage_Time_Up_Value(&manage_time.time_on[1]);
			}			
		}
	}
	else if( manage_flg.edit_mode == EDIT_TIME_MODE_OFF_DISP)
	{
		if( manage_time.time_off[0] == FALSE)
		{
			manage_time.time_off[0] = TRUE;		
			Manage_Time_Up_Value(&manage_time.time_off[1]);
		}
		else
		{
			// if(manage_flg.edit_flag==EDIT_TIME_FLAG_HOUR && (manage_time.time_off[1]+1) > 23)
			// {
				// manage_time.time_off[0] = FALSE;		
			// }
			// else
			{
				Manage_Time_Up_Value(&manage_time.time_off[1]);
			}			
		}
	}	
}

/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Time_Down_Value                                        * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Time_Down_Value(signed char * p_value)
{	
	if(manage_flg.edit_flag==EDIT_TIME_FLAG_HOUR)
	{
		if(p_value[0] <= 0)
		{
			p_value[0] = 23;
		}
		else
		{
			p_value[0]--;
		}
	}
	else if(manage_flg.edit_flag==EDIT_TIME_FLAG_MINUTE)
	{
		if(p_value[1] <= 0)
		{
			p_value[1] = 59;
		}
		else
		{
			p_value[1]--;
		}
	}
}


/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Time_Down_Disp                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Time_Down_Disp(void)
{
	if( manage_flg.edit_mode == EDIT_TIME_MODE_CURR_DISP)
	{
		Manage_Time_Down_Value((signed char *)&manage_time.curr[1]);
	}
	else if( manage_flg.edit_mode == EDIT_TIME_MODE_ON_DISP)
	{
		if( manage_time.time_on[0] == FALSE)
		{
			manage_time.time_on[0] = TRUE;		
			Manage_Time_Down_Value((signed char *)&manage_time.time_on[1]);
		}
		else
		{
			// if(manage_flg.edit_flag==EDIT_TIME_FLAG_HOUR && (manage_time.time_on[1]-1) == 0)
			// {
				// manage_time.time_on[0] = FALSE;		
			// }
			// else
			{
				Manage_Time_Down_Value((signed char *)&manage_time.time_on[1]);
			}			
		}
	}
	else if( manage_flg.edit_mode == EDIT_TIME_MODE_OFF_DISP)
	{
		if( manage_time.time_off[0] == FALSE)
		{
			manage_time.time_off[0] = TRUE;		
			Manage_Time_Down_Value((signed char *)&manage_time.time_off[1]);
		}
		else
		{
			// if(manage_flg.edit_flag==EDIT_TIME_FLAG_HOUR && (manage_time.time_off[1]-1) == 0)
			// {
				// manage_time.time_off[0] = FALSE;		
			// }
			// else
			{
				Manage_Time_Down_Value((signed char *)&manage_time.time_off[1]);
			}			
		}
	}
}


/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Time_Down_Disp                                           * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Time_enable(char enable)
{
	if( manage_flg.edit_mode == EDIT_TIME_MODE_ON_DISP)
	{
		manage_time.time_on[0] = enable;		
	}
	else if( manage_flg.edit_mode == EDIT_TIME_MODE_OFF_DISP)
	{
		manage_time.time_off[0] = enable;		
	}
}

/********************************************************************************
 *                                                                              *
 *  TASK:           ManageSetLampControl                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void ManageSetLampControl(char on_off)
{
	if(on_off == TRUE)
	{
		LAMP_CTR_PORT |= _BV(LAMP_CTR);
	}
	else
	{
		LAMP_CTR_PORT &= ~_BV(LAMP_CTR);
	}
}


/********************************************************************************
 *                                                                              *
 *  TASK:           ManageGetLampPort                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
char ManageGetLampPort(void)
{	
	char output_port;
	
	if((LAMP_CTR_PIN | _BV(LAMP_CTR)) == 0)
	{
		output_port = FALSE;
	}
	else
	{
		output_port = TRUE;
	}
	
	return output_port;
}

/********************************************************************************
 *                                                                              *
 *  TASK:           TaskManage                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Command_Process(void)
{
	if(BuffPeekFifo(Manage_Command_Buff) != FIFO_ERR)
	{
		switch( BuffPullFifo(Manage_Command_Buff) )
		{
			case MANAGE_TIME_MENU_DISP_CMD:
					Manage_Time_Menu_Disp();
				break;
			case MANAGE_TIME_DISP_CMD:
					Manage_Time_Disp(0,0 ms);
				break;
			case MANAGE_TOGGLE_DISP_CMD:
					Manage_Display_Toggle(0 ms);
				break;
			case MANAGE_TOGGLE_TIME_DISP_CMD:
					// Manage_Display_Toggle(250 ms);
					Manage_Display_Toggle(75 ms);
				break;				
			case MANAGE_TIME_ENABLE_CMD:
				Manage_Time_enable(TRUE);
				break;
			case MANAGE_TIME_DISABLE_CMD:
				Manage_Time_enable(FALSE);
				break;
			case MANAGE_TIME_UP_DISP_CMD:
					Manage_Time_Up_Disp();
					Manage_Display_Toggle(0 ms);	
				break;
			case MANAGE_TIME_UP_CONT_DISP_CMD:
					Manage_Time_Up_Disp();
					Manage_Time_Disp(0,0 ms);
					BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_UP_CONT_DISP_CMD);
					manage_flg.cmd_time_out = MANAGE_CMD_TIMEOUT;	
				break;
			case MANAGE_TIME_DOWN_DISP_CMD:
					Manage_Time_Down_Disp();
					Manage_Display_Toggle(0 ms);					
				break;
			case MANAGE_TIME_DOWN_CONT_DISP_CMD:
					Manage_Time_Down_Disp();
					Manage_Time_Disp(0,0 ms);
					BuffPutFifo(Manage_Command_Buff,MANAGE_TIME_DOWN_CONT_DISP_CMD);
					manage_flg.cmd_time_out = MANAGE_CMD_TIMEOUT;	
				break;				
			case MANAGE_TIME_CURR_SETUP_CMD:
					Manage_Disp_Time_Setup(TRUE);
				break;				
			case MANAGE_WRITE_EPPROM_TIME_ON_CMD:
					ManageEppromTimeOn(1);
				break;
			case MANAGE_READ_EPPROM_TIME_ON_CMD:
					ManageEppromTimeOn(0);
				break;
			case MANAGE_WRITE_EPPROM_TIME_OFF_CMD:
					ManageEppromTimeOff(1);
				break;
			case MANAGE_READ_EPPROM_TIME_OFF_CMD:
					ManageEppromTimeOff(0);
				break;
			case MANAGE_SET_LAMP_ON_CMD:
					ManageSetLampControl(TRUE);
				break;
			case MANAGE_SET_LAMP_OFF_CMD:
					ManageSetLampControl(FALSE);
				break;
			case MANAGE_SET_LAMP_ON_DISP_CMD:
					Manage_Display_Output_port(TRUE);			
				break;
			case MANAGE_SET_LAMP_OFF_DISP_CMD:
					Manage_Display_Output_port(FALSE);			
				break;
			case MANAGE_SET_BLACK_OUT_CMD:
					Manage_Black_Out_Disp();
				break;
			case MANAGE_TIME_CURR_DISP_CMD:
					Manage_Disp_Time();
				break;
			default:
				break;
		}
	}
}


/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Lamp_Control                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Lamp_Control(void)
{
	static char output_port = FALSE;
	
	if(manage_flg.edit_flag == EDIT_TIME_FLAG_NONE)
	{
		if(manage_time.time_on[0]==TRUE && manage_time.curr[1]==manage_time.time_on[1] && manage_time.curr[2]==manage_time.time_on[2])
		{
			//if(ManageGetLampPort() == FALSE) 
			if(output_port == FALSE) 
			{
				BuffPutFifo(Manage_Command_Buff,MANAGE_SET_LAMP_ON_CMD);
				BuffPutFifo(Manage_Command_Buff,MANAGE_SET_LAMP_ON_DISP_CMD); 
				output_port = TRUE;
			}
		}

		else if(manage_time.time_off[0]==TRUE && manage_time.curr[1]==manage_time.time_off[1] && manage_time.curr[2]==manage_time.time_off[2])
		{
			//if(ManageGetLampPort() == TRUE)
			if(output_port == TRUE)
			{
				BuffPutFifo(Manage_Command_Buff,MANAGE_SET_LAMP_OFF_CMD); 
				BuffPutFifo(Manage_Command_Buff,MANAGE_SET_LAMP_OFF_DISP_CMD); 
				output_port = FALSE;
			}			
		}
	}
}

/********************************************************************************
 *                                                                              *
 *  TASK:           Manage_Process_End                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void Manage_Process_End(void)
{
	if(manage_flg.cmd_time_out > 0)
	{
		manage_flg.cmd_black_out = MANAGE_CMD_BLACK_OUT;
		manage_flg.cmd_time_out -= 100 ms;
		//manage_flg.cmd_time_out -= 50 ms;
		if(manage_flg.cmd_time_out <= 0 ms)
		{
			if(manage_flg.edit_mode == EDIT_TIME_MODE_ON_DISP)
			{
				BuffPutFifo(Manage_Command_Buff, MANAGE_READ_EPPROM_TIME_ON_CMD);							
			}
		
			if(manage_flg.edit_mode == EDIT_TIME_MODE_OFF_DISP)
			{
				BuffPutFifo(Manage_Command_Buff, MANAGE_READ_EPPROM_TIME_OFF_CMD);
			}
		
			Manage_Disp_Time_Setup(FALSE);
			manage_flg.prv_key = KEY_NULL_CODE;
			manage_time.curr[0] = TRUE;
			manage_flg.edit_flag = EDIT_TIME_FLAG_NONE;
			manage_flg.edit_mode = EDIT_TIME_MODE_NONE;
			//@TH printf("Cmd Time Out\r\n");
		}
	}
	
	if(manage_flg.cmd_black_out > 0)
	{
		manage_flg.cmd_black_out -= 100 ms;
		if( manage_flg.cmd_black_out <= 0 ms)
		{
			BuffPutFifo(Manage_Command_Buff, MANAGE_SET_BLACK_OUT_CMD);
		}
	}
	
}


/********************************************************************************
 *                                                                              *
 *  TASK:           TaskManage                                                   * 
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    
 *
 ********************************************************************************/
void TaskManage (void)
{
	static char TaksManageSwitchTask = 0;
	//@TH printf( cVersion );

	BuffPutFifo(Manage_Command_Buff, MANAGE_READ_EPPROM_TIME_ON_CMD);				
	BuffPutFifo(Manage_Command_Buff, MANAGE_READ_EPPROM_TIME_OFF_CMD);				
	
    for (;;)
    {	
		OS_Delay( MANAGE_TIME_INTERVAL );						
		
		Keyin_Mail_Manage();				
		
		switch( TaksManageSwitchTask++ )
		{
			case 0:
					RTC_Mail_Manage();
				break;
			case 1:
					Manage_Disp_Time_Update();
				break;
			case 2:
					Manage_Command_Process();
				break;
			case 3:
					Manage_Lamp_Control();
				break;
			default:
					Manage_Process_End();
					TaksManageSwitchTask = 0;
				break;			
		}
		
    }
}
